home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
presto
/
prest_04.lha
/
src
/
swtch.s
< prev
next >
Wrap
Text File
|
1989-08-08
|
5KB
|
212 lines
/*
* Switch routines
*
* save all registers
* disable interrupts
* remember current sp and fp
* restore old sp and fp
* enable interrupts
* restore old registers on return
*/
/*
* Context Switch
*
* This routine must be atomic (nonpreemptable).
* This file contains the code for three different hardware
* systems. They should be broken out into separate files,
* but hey...
*/
#ifdef ns32000
.file "swtch.s"
.text
.align 2
.globl __Thread_swtch
__Thread_swtch:
# _au0_this is in 8(fp)
# save r0 through r7
# must save even scratch registers since we may have been
# preempted.
enter [r0,r1,r2,r3,r4,r5,r6,r7],0
#
# WARNING: The following offsets depend on the setup of class
# Thread and all those from which it is derived
#
#
movqd 0, _interrupts_enabled;
movd 20(8(fp)), r0 # r0 = this->t_csp
movd 24(8(fp)), r1 # r1 = this->t_fp
sprd sp, 20(8(fp)) # this->t_csp = sp
sprd fp, 24(8(fp)) # this->t_fp = fp
lprd sp, r0 # sp = (old)this->t_csp
lprd fp, r1 # fp = (old)this->t_fp
movqd 1, _interrupts_enabled;
#
# restore regs
#
exit [r0,r1,r2,r3,r4,r5,r6,r7]
ret 0
#endif
#ifdef i386
.file "swtch.s"
.text
.align 2
.globl __Thread_swtch
__Thread_swtch:
#
# _au0_this is in 4(%esp) at entry.
# No need to save scratch registers since preemption code does that.
#
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
#
# WARNING: The following offsets depend on the setup of class
# Thread and all those from which it is derived
#
movl $0, _interrupts_enabled;
movl 8(%ebp), %eax # eax == "this"
xchgl %esp, 20(%eax) # swap stack-pointer with thread
xchgl %ebp, 24(%eax) # swap frame-pointer with thread
movb $1, _interrupts_enabled;
#
# restore regs
#
popl %ebx
popl %esi
popl %edi
leave
ret
/*
* init_stack(Thread* newthread, int* new_stack_top)
* Push a proper "swtch" register context, so next swtch() in
* newthread restores registers correctly and returns to caller's caller.
* Save apprioriate stack and frame pointer in thread.
*
* Called in Thread::runrun().
*
* Assumes caller has no register variables, thus current contents are
* appropriate for caller's caller.
*/
.text
.align 2
.globl _init_stack
_init_stack:
popl %ecx # ecx = return address
popl %eax # eax -> thread
popl %edx # edx = new stack top
pushl %edi # push registers ...
pushl %esi # ... ala swtch()
pushl %ebx # ... entry.
movl %esp, 20(%eax) # save callers stack pointer in thread
movl %ebp, 24(%eax) # save callers frame pointer in thread
leal -8(%edx), %esp # on new stack, room for caller to pop args
jmp *%ecx # return
#endif
/*
* The vax version of swtch assumes that "this" points to a thread whose
* t_proc field points to the process object corresponding to the context in
* which swtch is executing. Thus "this->t_proc->p_interruptible" controls
* preemption of the process executing swtch.
*/
#ifdef vax
.file "swtch.s"
.text
.data
.text
.align 2
.globl __Thread_swtch
__Thread_swtch:
.word 0xfff # entry mask (save regs r0-r11)
movl 4(ap), r2 # r2 = this
movl 28(r2), r3 # r3 = this->t_proc
movl $0, 20(r3) # this->t_proc->p_interruptible = 0
movl 24(r2), r1 # r1 = this->t_fp
movl fp, 24(r2) # this->t_fp = fp
movl r1, fp # fp = (old)this->t_fp
movl $1, 20(r3) # this->t_proc->p_interruptible = 1
ret
#endif vax
#ifdef mc68020
|
| _Thread_swtch and init_stack routines for the mc68020 -- Jim Carson 1/2/89
|
.data
.lcomm _swtch_tmp, 4
.even
.text
.even
.globl __Thread_swtch
__Thread_swtch:
link a6, #0
movl a3, sp@-
movl a4, sp@-
movl a5, sp@-
#ifdef THREAD_HAS_INTERRUPTIBLE_FIELD
movl a6@(8), a0 | this
movl a0@(28), a0 | ->proc
clrl a0@(20) | ->p_interruptible = 0
#else
clrl _interrupts_enabled
#endif
movl a6@(8), a0 | a0 == "this"
movl a0@(20), _swtch_tmp | _swtch_tmp = this->t_csp
movl sp, a0@(20) | this->t_csp = sp
movl _swtch_tmp, sp | sp = _swtch_tmp
|
movl a0@(24), _swtch_tmp | _swtch_tmp = this->t_fp
movl a6, a0@(24) | this->t_fp = fp
movl _swtch_tmp, a6 | fp = _swtch_tmp
#ifdef THREAD_HAS_INTERRUPTIBLE_FIELD
movl a0@(28), a0 | this->proc
movl #1, a0@(20) | ->p_interruptible = 1
#else
movl #1, _interrupts_enabled
#endif
movl sp@+, a5
movl sp@+, a4
movl sp@+, a3
unlk a6
rts
.globl f68881_used
|
| init_stack(Thread* newthread, int* new_stack_top)
|
.text
.align 2
.globl _init_stack
_init_stack:
movl sp@+, a0 | a0 = return address
movl sp@+, a1 | a1 = thread
movl sp@+, a2 | a2 = new stack top
movl a3, sp@- | push registers ...
movl a4, sp@- | ... ala swtch()
movl a5, sp@- | ... entry.
movl sp, a1@(20) | Save caller's stack ptr in thread
movl a6, a1@(24) | Save caller's frame ptr in thread
lea a2@(-8), sp | On new stack, room for caller to pop args
jmp a0@ | Return
#endif mc68020